﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace agTweener
{
    /// <summary>
    /// TweenParameter
    /// Holds all properties of an individual tween
    /// 
    /// author		Michael Cameron
    /// version		1.0.1
    /// Based on Flash Tweener Actionscript library by Zeh Fernando, Nate Chatellier
    /// Updated for Silverlight 2.0 Beta 1
    /// </summary>

    public class TweenParameter
    {
        public TransitionType transition = TransitionType.easeInExpo;
        public double time = 1;
        public double delay = 0;
        public Canvas TimerParent;
        public double[] DoubleArray = null;
        public double DoubleValue = Double.MinValue;
        public Point Point = new Point(Double.MinValue, Double.MinValue);
        public double LeftProperty = Double.MinValue;
        public double TopProperty = Double.MinValue;
        public double Width = Double.MinValue;
        public double Height = Double.MinValue;
        public double X = Double.MinValue;
        public double Y = Double.MinValue;
        public double ScaleX = Double.MinValue;
        public double ScaleY = Double.MinValue;
        public double SkewAngleX = Double.MinValue;
        public double SkewAngleY = Double.MinValue;
        public double RotateAngle = Double.MinValue;
        public double Opacity = Double.MinValue;
        public int ZIndex = int.MinValue;

        public TweenParameter()
        {
        }

        public void Init(FrameworkElement target)
        {
            if (target != null)
            {
                LeftProperty = (double)target.GetValue(Canvas.LeftProperty);
                TopProperty = (double)target.GetValue(Canvas.TopProperty);
                Width = (double)target.Width;
                Height = (double)target.Height;
                X = InitElementTranslate(target).X;
                Y = InitElementTranslate(target).Y;
                ScaleX = InitElementScale(target).ScaleX;
                ScaleY = InitElementScale(target).ScaleY;
                SkewAngleX = InitElementSkew(target).AngleX;
                SkewAngleY = InitElementSkew(target).AngleY;
                RotateAngle = InitElementRotate(target).Angle;
                Opacity = (double)target.Opacity;
                ZIndex = (int)target.GetValue(Canvas.ZIndexProperty);
            }
        }

        private TranslateTransform InitElementTranslate(FrameworkElement target)
        {
            // if there's an existing ScaleTransform on the target FrameworkElement find it and return it
            TranslateTransform st;
            st = (TranslateTransform)FindTransform(target, "TranslateTransform");
            if (st != null)
                return st;

            // if we're here then a RenderTransform doesn't exist for the FrameworkElement, so create one
            // first check for an existing TransformGroup 
            TransformGroup tg = FindTransformGroup(target);
            st = new TranslateTransform();

            tg.Children.Add(st);
            target.RenderTransform = tg;
            return st;
        }

        private ScaleTransform InitElementScale(FrameworkElement target)
        {
            // if there's an existing ScaleTransform on the target FrameworkElement find it and return it
            ScaleTransform st;
            st = (ScaleTransform)FindTransform(target, "ScaleTransform");
            if (st != null)
                return st;

            // if we're here then a RenderTransform doesn't exist for the FrameworkElement, so create one
            // first check for an existing TransformGroup 
            TransformGroup tg = FindTransformGroup(target);
            st = new ScaleTransform();

            tg.Children.Add(st);
            target.RenderTransform = tg;
            return st;
        }

        private SkewTransform InitElementSkew(FrameworkElement target)
        {
            // if there's an existing SkewTransform on the target FrameworkElement find it and return it
            SkewTransform st;
            st = (SkewTransform)FindTransform(target, "SkewTransform");
            if (st != null)
                return st;

            // if we're here then a RenderTransform doesn't exist for the FrameworkElement, so create one
            // first check for an existing TransformGroup 
            TransformGroup tg = FindTransformGroup(target);
            st = new SkewTransform();
            tg.Children.Add(st);
            target.RenderTransform = tg;
            return st;
        }

        private RotateTransform InitElementRotate(FrameworkElement target)
        {
            // if there's an existing RotateTransform on the target FrameworkElement find it and return it
            RotateTransform rt;
            rt = (RotateTransform)FindTransform(target, "RotateTransform");
            if (rt != null)
                return rt;

            // if we're here then a RenderTransform doesn't exist for the FrameworkElement, so create one
            // first check for an existing TransformGroup 
            TransformGroup tg = FindTransformGroup(target);
            rt = new RotateTransform();
            tg.Children.Add(rt);
            target.RenderTransform = tg;
            return rt;
        }

        internal Transform FindTransform(FrameworkElement target, string transformName)
        {
            if (target.RenderTransform as TransformGroup != null)
            {
                if (((TransformGroup)target.RenderTransform).Children.Count > 0)
                {
                    for (int i = 0; i < ((TransformGroup)target.RenderTransform).Children.Count; i++)
                    {
                        if (((TransformGroup)target.RenderTransform).Children[i].GetType().Name == transformName)
                        {
                            return (Transform)((TransformGroup)target.RenderTransform).Children[i];
                        }
                    }
                }
            }
            return null;
        }

        internal TransformGroup FindTransformGroup(FrameworkElement target)
        {
            if (target.RenderTransform as TransformGroup != null)
            {
                return (TransformGroup)target.RenderTransform;
            }
            // if TransformGroup doesn't exist then return a new one
            return new TransformGroup();
        }

    }
}
